package dan.common
import chisel3._
import chisel3.util._

object ExpCode {
    val eCodeBits = 6
    val esubCodeBits = 9
    val expBits = eCodeBits + esubCodeBits
    val microExpBits = 6
    
    def INT = 0x0.U(eCodeBits.W)    // 中断
    def PIL = 0x1.U(eCodeBits.W)    // load页无效
    def PIS = 0x2.U(eCodeBits.W)    //store页无效
    def PIF = 0x3.U(eCodeBits.W)    //取值页无效
    def PME = 0x4.U(eCodeBits.W)    //修改页无效
    def PPI = 0x7.U(eCodeBits.W)    //特权等级违规
    def ADEF = 0x8.U(eCodeBits.W)   //取指地址错
    def ALE = 0x9.U(eCodeBits.W)    //地址非对齐
    def SYS = 0xb.U(eCodeBits.W)    //系统调用
    def BRK = 0xc.U(eCodeBits.W)    //断点
    def INE = 0xd.U(eCodeBits.W)    //指令不存在
    def TLBR = 0x3f.U(eCodeBits.W)  //TLB重填
    def MINI_EXCEPTION_MEM_ORDERING = 0x1a.U(eCodeBits.W)   //内部异常，LSU写后读
    def MINI_EXCEPTION_L0TLB_MISS   = 0x1b.U(eCodeBits.W)   //内部异常，L0 TLB miss

    def microExp2Major(microExp: UInt): UInt = microExp
    def microExp2Sub(microExp: UInt): UInt = 0.U(esubCodeBits.W)
}

object Consts {
    val X = BitPat("b?")
    val Y = BitPat("b1")
    val N = BitPat("b0")
    // Control Status Register
    val CSR_BITS = 4
    val CSR_N  =  0.U(CSR_BITS.W)  // 非CSR指令
    val CSR_R  =  1.U(CSR_BITS.W)  // csrrd
    val CSR_W  =  2.U(CSR_BITS.W)  // csrwr
    val CSR_M  =  3.U(CSR_BITS.W)  // csrxchg
    val CSR_E  =  4.U(CSR_BITS.W)  // ertn
    val CSR_I  =  5.U(CSR_BITS.W)  // idle
    val TLB_S  =  6.U(CSR_BITS.W)  // tlbsrch
    val TLB_R  =  7.U(CSR_BITS.W)  // tlbrd
    val TLB_W  =  8.U(CSR_BITS.W)  // tlbwr
    val TLB_F  =  9.U(CSR_BITS.W)  // tlbfill
    val TLB_I  = 10.U(CSR_BITS.W)  // invtlb 
    // Control Flow Instruction
    val CFI_BITS = 2
    val CFI_N    = 0.U(CFI_BITS.W) // Not a CFI instruction
    val CFI_BR   = 1.U(CFI_BITS.W) // Branch
    val CFI_BL   = 2.U(CFI_BITS.W) // BL
    val CFI_JIRL = 3.U(CFI_BITS.W) // JIRL
    // Issue Queue Type
    val IQT_BITS = 2
    val IQT_X = BitPat.dontCare(IQT_BITS)
    val IQT_INT = 1.U(IQT_BITS.W)
    val IQT_MEM = 2.U(IQT_BITS.W)
    // Function Unit
    val FU_BITS = 8
    val FU_X = BitPat.dontCare(FU_BITS)
    val FU_ALU = 1.U(FU_BITS.W)
    val FU_JMP = 2.U(FU_BITS.W)
    val FU_MEM = 4.U(FU_BITS.W)
    val FU_MUL = 8.U(FU_BITS.W)
    val FU_DIV = 16.U(FU_BITS.W)
    val FU_CSR = 32.U(FU_BITS.W)
    val FU_CNT = 64.U(FU_BITS.W)
    // Register Operand Type
    val REGT_BITS = 1
    val REGT_N = 0.U(REGT_BITS.W) // Not a register
    val REGT_GPR = 1.U(REGT_BITS.W) // General Purpose Register
    // Immediate Type
    /* 
        0	immU5	无符号 5 位立即数。用于位移等。位于指令 [14:10]，高位补0填充为32位。
        1	immU12	无符号 12 位立即数。来自 [21:10]，高20位补0。常用于 load/store 偏移等。
        2	immS12	符号扩展 12 位立即数。高20位复制符号位（bit 21），用于一些有符号运算。
        3	immS14	符号扩展 14 位立即数。由 [23:10] 构造 + 填充低 2 位 0。
        4	immS16	符号扩展 16 位立即数。来自 [25:10] 构造 + 填充低 2 位 0。
        5	immU20	20 位无符号立即数（高位）。来自 [24:5] + 12 个0，常用于 LU12I.W 这样的指令。
        6	immS20	20 位符号扩展立即数。高10位为符号扩展 [24]，接着 [24:5]，再填充低2位0。
        7	immS26	符号扩展 26 位立即数。由 [25:10]、[9:0] 拼接后扩展符号 + 填0，常用于跳转指令等。
        8	immCSR	CSR 地址立即数，用于访问 CSR 寄存器。格式自定义。
        9	immCID	CSR ID 立即数（可能是 CSR 指令里的 UIMM5 或指令编码中的 ID 字段）。
     */
    val IMMT_BITS = 4
    val IMM_X = BitPat.dontCare(IMMT_BITS)
    val IMM_U5 = 0.U(IMMT_BITS.W)
    val IMM_U12 = 1.U(IMMT_BITS.W)
    val IMM_S12 = 2.U(IMMT_BITS.W)
    val IMM_S14 = 3.U(IMMT_BITS.W)
    val IMM_S16 = 4.U(IMMT_BITS.W)
    val IMM_U20 = 5.U(IMMT_BITS.W)
    val IMM_S20 = 6.U(IMMT_BITS.W)
    val IMM_S26 = 7.U(IMMT_BITS.W)
    val IMM_CSR = 8.U(IMMT_BITS.W)
    val IMM_CID = 9.U(IMMT_BITS.W)
    // Branch Instruction
    val BR_BITS = 4
    val BR_N = 0.U(BR_BITS.W)
    val BR_NE = 1.U(BR_BITS.W)   // Branch Not Equal
    val BR_EQ = 2.U(BR_BITS.W)   // Branch Equal
    val BR_GE = 3.U(BR_BITS.W)   // Branch Greater or Equal
    val BR_GEU = 4.U(BR_BITS.W)  // Branch Greater or Equal Unsigned
    val BR_LT = 5.U(BR_BITS.W)   // Branch Less Than
    val BR_LTU = 6.U(BR_BITS.W)  // Branch Less Than Unsigned
    val BR_J = 7.U(BR_BITS.W)   // Jump
    val BR_JR = 8.U(BR_BITS.W)  // Jump Register
    // Next PC Select
    val PCSEL_BITS = 2
    val PC_ADD4 = 0.U(PCSEL_BITS.W) // PC + 4
    val PC_JUMP = 1.U(PCSEL_BITS.W) // Jump
    val PC_JIRL = 2.U(PCSEL_BITS.W) // Jump Indirect Register Link
    // Operand 1 Type
    val OP1T_BITS = 2
    val OP1T_X = BitPat.dontCare(OP1T_BITS)
    val OP1T_RS = 0.U(OP1T_BITS.W) // Register Source 1
    val OP1T_ZERO = 1.U(OP1T_BITS.W) // const zero
    val OP1T_PC = 2.U(OP1T_BITS.W)  // PC
    // Operand 2 Type
    val OP2T_BITS = 3
    val OP2T_X = BitPat.dontCare(OP2T_BITS)
    val OP2T_RS = 0.U(OP2T_BITS.W) // Register Source 2
    val OP2T_IMM = 1.U(OP2T_BITS.W) // Immediate
    val OP2T_ZERO = 2.U(OP2T_BITS.W) // const zero
    val OP2T_NEXT = 3.U(OP2T_BITS.W) // fixed const 4
    // Bubble instruction
    val BUBBLE = 0.U(32.W) 
    // 基本整数指令
    val UOP_BITS = 7
    val UOP_X = BitPat.dontCare(UOP_BITS)
    val UOP_NOP = 0.U(UOP_BITS.W)
    val UOP_ADD = 1.U(UOP_BITS.W)
    val UOP_SUB = 2.U(UOP_BITS.W)
    val UOP_SLT = 3.U(UOP_BITS.W)
    val UOP_SLTU = 4.U(UOP_BITS.W)
    val UOP_NOR = 5.U(UOP_BITS.W)
    val UOP_AND = 6.U(UOP_BITS.W)
    val UOP_OR = 7.U(UOP_BITS.W)
    val UOP_XOR = 8.U(UOP_BITS.W)
    val UOP_LU12IW = 9.U(UOP_BITS.W)
    val UOP_ADDIW = 10.U(UOP_BITS.W)
    val UOP_SLTI = 11.U(UOP_BITS.W)
    val UOP_SLTUI = 12.U(UOP_BITS.W)
    val UOP_PCADDI = 13.U(UOP_BITS.W)
    val UOP_PCADDU12I = 14.U(UOP_BITS.W)
    val UOP_ANDN = 15.U(UOP_BITS.W)
    val UOP_ORN = 16.U(UOP_BITS.W)
    val UOP_ANDI = 17.U(UOP_BITS.W)
    val UOP_ORI = 18.U(UOP_BITS.W)
    val UOP_XORI = 19.U(UOP_BITS.W)
    val UOP_MULW = 20.U(UOP_BITS.W)
    val UOP_MULHW = 21.U(UOP_BITS.W)
    val UOP_MULHWU = 22.U(UOP_BITS.W)
    val UOP_DIVW = 23.U(UOP_BITS.W)
    val UOP_MODW = 24.U(UOP_BITS.W)
    val UOP_DIVWU = 25.U(UOP_BITS.W)
    val UOP_MODWU = 26.U(UOP_BITS.W)
    val UOP_SLLIW = 27.U(UOP_BITS.W)
    val UOP_SRLIW = 28.U(UOP_BITS.W)
    val UOP_SRAIW = 29.U(UOP_BITS.W)
    val UOP_SLLW = 30.U(UOP_BITS.W)
    val UOP_SRLW = 31.U(UOP_BITS.W)
    val UOP_SRAW = 32.U(UOP_BITS.W)
    // 分支指令
    val UOP_JIRL = 33.U(UOP_BITS.W)
    val UOP_BL = 34.U(UOP_BITS.W)
    val UOP_BEQ = 36.U(UOP_BITS.W)
    val UOP_BNE = 37.U(UOP_BITS.W)
    val UOP_BLT = 38.U(UOP_BITS.W)
    val UOP_BGE = 39.U(UOP_BITS.W)
    val UOP_BLTU = 40.U(UOP_BITS.W)
    val UOP_BGEU = 41.U(UOP_BITS.W)
    // CSR指令
    val UOP_ERET = 42.U(UOP_BITS.W)
    val UOP_CSRRD = 43.U(UOP_BITS.W)
    val UOP_CSRWR = 44.U(UOP_BITS.W)
    val UOP_CSRXCHG = 45.U(UOP_BITS.W)
    
    val UOP_IDLE = 46.U(UOP_BITS.W)
    // TLB
    val UOP_TLBSRCH = 47.U(UOP_BITS.W)
    val UOP_TLBRD = 48.U(UOP_BITS.W)
    val UOP_TLBWR = 49.U(UOP_BITS.W)
    val UOP_TLBFILL = 50.U(UOP_BITS.W)
    val UOP_INVTLB = 51.U(UOP_BITS.W)
    // Cache
    val UOP_CACOP = 52.U(UOP_BITS.W)
    val UOP_PRELD = 53.U(UOP_BITS.W)
    val UOP_DBAR = 54.U(UOP_BITS.W)
    // 访存子命令
    /* 
        STA - 计算 Store Address
        STD - 计算 Store Data
     */
    val UOP_LD = 55.U(UOP_BITS.W)
    val UOP_STA = 56.U(UOP_BITS.W)
    val UOP_STD = 57.U(UOP_BITS.W)
    // LL-SC
    val UOP_LLW = 58.U(UOP_BITS.W)
    val UOP_SC_AG = 59.U(UOP_BITS.W)  // Store-Conditional Address Generation
    // 计数器
    val UOP_RDCNTIDW = 60.U(UOP_BITS.W)
    val UOP_RDCNTVLW = 61.U(UOP_BITS.W)
    val UOP_RDCNTVHW = 62.U(UOP_BITS.W)
    val UOP_RDTIMELW = 63.U(UOP_BITS.W)   // 合并RDCNTIDW 以及 RDCNTVLW ??
    // 等价于UOP_NOP
    val UOP_MOV = 64.U(UOP_BITS.W)
    def nullUOp: UOp = {
        val uop = Wire(new UOp)
        // TODO
        uop := DontCare
        uop.uopType := UOP_NOP
        uop.bypassable := false.B
        uop.useStQ    := false.B
        uop.useLdQ    := false.B
        uop.physDst       := 0.U
        uop.archDstType  := REGT_N

        val cs = Wire(new CtrlSignal())
        cs := DontCare
        cs.brType := BR_N
        cs.csrCmd := CSR_N
        cs.isLd := false.B
        cs.isStA  := false.B
        cs.isStD  := false.B

        uop.ctrl := cs
        return uop
    }
    // parameters
    val TLB_SIZE: Int = 32
    val TLB_IDX_BITS:Int = 5
    // CSR.XXX configuration
    val TLBIDX_R_BITS: Int = 16 - TLB_IDX_BITS
    val TLBIDX_Index:Int = TLB_IDX_BITS     // maybe unused
    val PA_BITS:Int = 32
    val TLBELO_R_BITS:Int = 36 - PA_BITS 
    val TLBELO_PPN_BITS:Int = PA_BITS - 12
    val TIMER_BITS:Int = 32
    val TCFG_InitVal_BITS:Int = TIMER_BITS - 2
    // CSR.XXX address
    val CSR_ADDR_BITS = 14
    val CSR_CRMD = 0.U(CSR_ADDR_BITS.W)
    val CSR_PRMD = 1.U(CSR_ADDR_BITS.W)
    val CSR_EUEN = 2.U(CSR_ADDR_BITS.W)
    val CSR_ECFG = 4.U(CSR_ADDR_BITS.W)
    val CSR_ESTAT = 5.U(CSR_ADDR_BITS.W)
    val CSR_ERA = 6.U(CSR_ADDR_BITS.W)
    val CSR_BADV = 7.U(CSR_ADDR_BITS.W)
    val CSR_EENTRY = 12.U(CSR_ADDR_BITS.W)
    val CSR_TLBIDX = 16.U(CSR_ADDR_BITS.W)
    val CSR_TLBEHI = 17.U(CSR_ADDR_BITS.W)
    val CSR_TLBELO0 = 18.U(CSR_ADDR_BITS.W)
    val CSR_TLBELO1 = 19.U(CSR_ADDR_BITS.W)
    val CSR_ASID = 24.U(CSR_ADDR_BITS.W)
    val CSR_PGDL = 25.U(CSR_ADDR_BITS.W)
    val CSR_PGDH = 26.U(CSR_ADDR_BITS.W)
    val CSR_PGD = 27.U(CSR_ADDR_BITS.W)
    val CSR_CPUID = 32.U(CSR_ADDR_BITS.W)
    val CSR_SAVE0 = 48.U(CSR_ADDR_BITS.W)
    val CSR_SAVE1 = 49.U(CSR_ADDR_BITS.W)
    val CSR_SAVE2 = 50.U(CSR_ADDR_BITS.W)
    val CSR_SAVE3 = 51.U(CSR_ADDR_BITS.W)
    val CSR_TID = 64.U(CSR_ADDR_BITS.W)
    val CSR_TCFG = 65.U(CSR_ADDR_BITS.W)
    val CSR_TVAL = 66.U(CSR_ADDR_BITS.W)
    val CSR_TICLR = 68.U(CSR_ADDR_BITS.W)
    val CSR_LLBCTL = 96.U(CSR_ADDR_BITS.W)
    val CSR_TLBRENTRY = 136.U(CSR_ADDR_BITS.W)
    val CSR_CTAG = 152.U(CSR_ADDR_BITS.W)
    val CSR_DMW0 = 384.U(CSR_ADDR_BITS.W)
    val CSR_DMW1 = 385.U(CSR_ADDR_BITS.W) 

    val FPGA_RUN = true
}

object FlushType {
    def FLUSHT_BITS:Int = 3
    def apply() = UInt(FLUSHT_BITS.W)
    def NONE = 0.U  
    def EXP = 1.U   // 异常刷新
    def ERET = 2.U  // 异常返回
    def RE_FETCH = 3.U
    def STEP4 = 4.U

    def useExpVec(flushType: UInt): Bool = flushType === ERET || flushType === EXP
    def useOriginPC(flushType: UInt): Bool = flushType === RE_FETCH
    // re-implement with MuxCase
    def getType(valid: Bool, isExp: Bool, isEret: Bool, isReFetch: Bool): UInt = {
        MuxCase(STEP4, Seq(
            !valid -> NONE,
            isExp -> EXP,
            isEret -> ERET,
            isReFetch -> RE_FETCH
        ))
    }
}